home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
edit
/
dte5_1.zip
/
FINDREP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-06
|
34KB
|
1,133 lines
/*
* Written by Douglas Thomson (1989/1990)
*
* This source code is released into the public domain.
*/
/*
* Name: dte - Doug's Text Editor program - find/replace module
* Purpose: This file contains the functions relating to finding text
* and replacing text.
* It also contains the code for moving the cursor to various
* other positions in the file.
* File: findrep.c
* Author: Douglas Thomson
* System: this file is intended to be system-independent
* Date: October 1, 1989
*/
#ifdef HPXL
#include "commonh"
#include "findreph"
#include "utilsh"
#else
#include "common.h"
#include "findrep.h"
#include "utils.h"
#endif
/*
* prototypes for all functions in this file
*/
int set_flags ARGS((char *flag_str, int *flags, int *count));
int get_flags ARGS((int lines));
int mystrcmp ARGS((char *s1, char *s2));
int mystrcmpi ARGS((char *s1, char *s2));
void on_screen ARGS((windows *window, text_ptr cursor, int last));
void do_replace ARGS((windows *window, text_ptr start));
void do_last ARGS((windows *window));
void find_string ARGS((windows *window));
void replace_string ARGS((windows *window));
void goto_prep ARGS((windows *window));
void goto_complete ARGS((windows *window, text_ptr cursor));
void goto_marker ARGS((windows *window, int n));
void goto_top_file ARGS((windows *window));
void goto_end_file ARGS((windows *window));
text_ptr scan_forward ARGS((text_ptr start, char *opp, char *target));
text_ptr scan_backward ARGS((text_ptr start, char *opp, char *target));
void match_pair ARGS((windows *window, int forward));
void goto_line ARGS((windows *window));
/*
* find and replace flags
*/
#define F_BACKWARD 0x01 /* search backwards through file */
#define F_GLOBAL 0x02 /* search entire file */
#define F_LOCAL 0x04 /* search only marked block */
#define F_AUTO 0x08 /* behave as if user always answered yes */
#define F_IGNORE 0x10 /* ignore case differences */
#define F_WORD 0x20 /* match whole words only */
#define F_MATCH 0x40 /* match the case of the text being replaced */
/*
* Name: set_flags
* Purpose: To set up find and replace flags.
* Date: October 1, 1989
* Passed: flag_str: the flags chosen by the user
* Returns: flags: the equivalent binary flags
* count: the repeat count embedded in the flags
* TRUE if flags were OK, FALSE otherwise
*/
int set_flags(flag_str, flags, count)
char *flag_str;
int *flags;
int *count;
{
char *p; /* used to scan through flag_str for flags */
/*
* start with no flags set, then add those chosen
*/
*flags = 0;
/*
* assume just a single find / replace required
*/
*count = 1;
/*
* scan flag_str to work out which flags were chosen
*/
for (p=flag_str; *p; ++p) {
if (isdigit(*p)) {
/*
* extract an embedded repeat count
*/
*count = atoi(p);
while (isdigit(*++p)) {
;
}
--p;
if (*count <= 0) {
error(WARNING, "bad repeat count: %d", *count);
*count = 1;
return FALSE;
}
}
else if ((*p = toupper(*p)) == 'B') {
*flags |= F_BACKWARD;
}
else if (*p == 'G') {
*flags |= F_GLOBAL;
*count = GLOB_COUNT;
}
else if (*p == 'L') {
*flags |= F_LOCAL;
*count = GLOB_COUNT;
}
else if (*p == 'N') {
*flags |= F_AUTO;
}
else if (*p == 'U') {
*flags |= F_IGNORE;
}
else if (*p == 'W') {
*flags |= F_WORD;
}
else if (*p == 'M') {
*flags |= F_MATCH;
}
else {
error(WARNING, "unknown flag: %c", *p);
return FALSE;
}
}
return TRUE;
}
/*
* Name: get_flags
* Purpose: To input find and replace flags.
* Date: October 1, 1989
* Passed: lines: no. of lines up from bottom of screen
* Returns: [g_status.flags]: binary flags set
* [g_status.flag_str]: flags as character string
* [g_status.search_count]: repeat find count
* OK if flags were entered, ERROR if user wanted to abort
*/
int get_flags(lines)
int lines;
{
char flag_str[MAX_COLS]; /* temporary copy of g_status.flag_str */
int flags; /* temporary copy of g_status.flags */
int count; /* temporary copy of g_status.count */
/*
* use the previous flags as the default
*/
strcpy(flag_str, g_status.flag_str);
/*
* keep on asking for flags until something acceptable is entered
*/
for (;;) {
if (get_name("Options (B,G,L,M,N,n,U,W): ", lines, flag_str) !=
OK) {
return ERROR;
}
if (set_flags(flag_str, &flags, &count)) {
break;
}
}
g_status.flags = flags;
g_status.search_count = count;
strcpy(g_status.flag_str, flag_str);
return OK;
}
/*
* Name: mystrcmp
* Purpose: To compare two strings up to the length of the first.
* Date: October 1, 1989
* Passed: s1: first string to compare
* s2: second string to compare
* Returns: 0 if strings match
* <0 if s1 < s2
* >0 if s1 > s2
*/
int mystrcmp(s1, s2)
char *s1;
char *s2;
{
for(;;) {
if (*s1 == '\0') {
return 0;
}
if (*s1 != *s2) {
return *s1 - *s2;
}
++s1;
++s2;
}
}
/*
* Name: mystrcmpi
* Purpose: To compare two strings up to the length of the first, ignoring
* case.
* Date: October 1, 1989
* Passed: s1: first string to compare
* s2: second string to compare
* Returns: 0 if strings match
* <0 if s1 < s2
* >0 if s1 > s2
*/
int mystrcmpi(s1, s2)
char *s1;
char *s2;
{
for(;;) {
if (*s1 == '\0') {
return 0;
}
if (tolower(*s1) != tolower(*s2)) {
return tolower(*s1) - tolower(*s2);
}
++s1;
++s2;
}
}
/*
* Name: on_screen
* Purpose: To move the cursor to a new position, without redrawing the
* window unless the new position is off the window.
* Date: October 1, 1989
* Passed: window: information allowing access to current window etc
* cursor: the new target position in the text
* last: the last line considered to be on the screen (this
* only affects the bottom window)
*/
void on_screen(window, cursor, last)
windows *window;
text_ptr cursor;
int last;
{
text_ptr p; /* used to scan from current cursor towards new one */
int line; /* used to count screen line */
/*
* if this is the bottom window displayed, then some lines at the
* bottom may need to be reserved for messages.
* Otherwise, the last line available is simply the bottom line used
* for the window.
*/
last = min(g_display.nlines-last-1, window->bottom_line);
line = window->cline;
if (window->cursor >= cursor) {
/*
* new cursor position is above old one
*/
for (p=window->cursor; ; p--) {
if (*p == '\n') {
--line;
}
if (line < window->top_line) {
/*
* off top of screen, so place in middle of display
*/
window->cline = window->place_line;
/*
* now check that we are not wasting the top part of the
* screen
*/
line = window->cline;
for (p=cursor; ; p--) {
if (*p == '\n') {
--line;
}
if (*p